package lambdasinaction.chap7;

import java.util.concurrent.ForkJoinPool;
import java.util.function.Function;

/**
 * Created by ThinkPad on 2017/8/22.
 * 并行流控制
 */
public class ParallelStreamHarness {

    public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool();

    public static void main(String[] args) {
//        用传统for循环很快,因为它更底层,不需要对原始类型做装箱拆箱
//        System.out.println("Iterative Sum done in: " +
//                measurePerf(ParallelStream::iterativeSum,10_000_000L) + " msecs");
//        System.out.println("Sequential Sum done in: " +
//                measurePerf(ParallelStream::sequentialSum,10_000_000L) + " msecs");
//        iterate生成的是装箱的对象,必须拆箱成数字才能求和
//        System.out.println("Parallel forkJoinSum done in: " +
//                measurePerf(ParallelStream::parallelSum,10_000_000L) + " msecs");
//        rangeClosed直接产生原始类型,没有装箱拆箱的开销
//        System.out.println("Range forkJoinSum done in: " +
//                measurePerf(ParallelStream::rangedSum,10_000_000L) + " msecs");
//        rengeClosed+parallel就很快了
//        System.out.println("Parallel range forkJoinSum done in: " +
//                measurePerf(ParallelStream::parallelRangedSum,10_000_000L) + " msecs");
//        性能比上一个差,因为必须先要把整个数字流都放进一个long[],之后才能在任务中使用它
        System.out.println("ForkJoin sum done in: " +
                measurePerf(ForkJoinSumCalculator::forkJoinSum,10_000_000L) + " msecs");
    }


    /**
     * 接受一个函数和一个参数,它会对传给方法的函数执行10次,记录每次执行的时间,
     * 并返回最短的一次执行时间
     * @param f 待测试的方法
     * @param input f方法的参数
     * @param <T>
     * @param <R>
     * @return
     */
    public static <T,R> long measurePerf(Function<T,R> f,T input) {
        long fastest = Long.MAX_VALUE;
        for (int i = 0;i < 10; i++) {
            long start = System.nanoTime();
            R result = f.apply(input);
            long duration = (System.nanoTime() - start) / 1_000_000;
            System.out.println("Result: " + result);
            if (duration < fastest) fastest = duration;
        }
        return fastest;
    }
}
